package com.net.xpay.web.controller.merchant;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.net.xpay.web.vo.OpenAppDevelopSettingsVo;
import com.net.xpay.web.vo.OpenAppShowDevelopSettingsVo;
import com.net.common.exception.BusinessException;
import com.net.common.model.ResultData;
import com.net.xpay.common.domain.User;
import com.net.xpay.common.domain.openapi.OpenApp;
import com.net.xpay.common.enums.openapi.OpenAppStatus;
import com.net.xpay.common.manager.UserShardManager;
import com.net.xpay.common.manager.openapi.OpenAppManager;
import com.net.xpay.common.model.DevelopSettingsModel;
import com.net.xpay.common.model.GetDevelopSettingsModel;
import com.net.xpay.common.model.ModifyOpenAppAppPublicKeyModel;
import com.net.xpay.common.model.ModifyOpenAppWhiteIpsModel;
import com.net.xpay.common.service.UserProfileService;
import com.net.xpay.common.util.JWTUtil;
import com.net.xpay.core.constant.PoseidonErrorCode;
import com.net.xpay.core.constant.WebConstant;
import com.net.xpay.core.domain.safePay.SafePayBookAccount;
import com.net.xpay.core.enums.SafePayBookAccountAuditStatus;
import com.net.xpay.core.manager.safePay.SafePayBookAccountManager;
import com.net.xpay.core.model.SafePayBookAccountSearchModel;
import com.net.xpay.web.secutiry.RequestUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.ArrayList;
import java.util.List;

/**
  on 10/02/2018.
 */
@RestController
@RequestMapping("/merchant/open-app")
@Api(tags = "商户/开放应用", description = "商户 开放应用 net")
@Slf4j
public class OpenAppController {

    @Autowired
    private UserProfileService userProfileService;

    @Autowired
    private OpenAppManager openAppManager;

    @Autowired
    private UserShardManager userShardManager;

    @Autowired
    private SafePayBookAccountManager safePayBookAccountManager;

    @ApiOperation(value = "开发设置配置情况")
    @GetMapping("show-develop-settings")
    public ResultData<OpenAppShowDevelopSettingsVo> showDevelopSettings(@ApiIgnore @RequestUser User user) {
        OpenAppShowDevelopSettingsVo vo = new OpenAppShowDevelopSettingsVo();

        OpenApp openApp = openAppManager.getByUserId(user.getId());
        if (openApp == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用尚未创建");
        }
        vo.setStatus(openApp.getStatus());
        vo.setAppId(openApp.getId().toString());
        vo.setAppPublicKeyIsSet(!Strings.isNullOrEmpty(openApp.getAppPublicKey()));
        vo.setWhiteIpsIsSet(CollectionUtils.isNotEmpty(openApp.getWhiteIps()));

        return new ResultData<>(vo);
    }

    @ApiOperation("应用上线")
    @PostMapping("/open")
    public ResultData<Boolean> openOpenApp(@ApiIgnore @RequestUser User user) {
        if (user.getId() == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用id不可为空");
        }
        OpenApp openApp = openAppManager.getByUserId(user.getId());
        if (openApp == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用不存在");
        }
        if (openApp.getStatus().equals(OpenAppStatus.OPEN)) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用已上线");
        }
        if (openApp.getAppPublicKey() == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用公钥未配置，请先完成应用公钥配置");
        }
        if (openApp.getWhiteIps() == null || openApp.getWhiteIps().size() == 0) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "IP白名单未配置，请先完成IP白名单配置");
        }
        //查询记账簿数量
        SafePayBookAccountSearchModel searchModel = new SafePayBookAccountSearchModel();
        searchModel.setUserId(user.getId());
        long count = safePayBookAccountManager.searchCount(searchModel);

        if (count == 1L) {
            SafePayBookAccount safePayBookAccount = safePayBookAccountManager.getByUserId(user.getId());
            if (!safePayBookAccount.getAuditStatus().equals(SafePayBookAccountAuditStatus.NORMAL)) {
                throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "企业未实名认证，请先完成企业实名认证");
            }
        }
        openApp.setStatus(OpenAppStatus.OPEN);
        openAppManager.update(openApp);
        return new ResultData<>(true);
    }

    @ApiOperation(value = "获取开发设置token")
    @PostMapping("/get-develop-settings-token")
    public ResultData<String> getDevelopSettingsToken(@ApiIgnore @RequestUser User user, @RequestBody DevelopSettingsModel model) {
        return new ResultData<>(userProfileService.getDevelopSettingsToken(user, model));
    }

    @ApiOperation(value = "获取开发设置信息")
    @PostMapping("get-develop-settings")
    @ResponseBody
    public ResultData<OpenAppDevelopSettingsVo> getDevelopSettings(@ApiIgnore @RequestUser User user, @RequestBody GetDevelopSettingsModel model) {
        Preconditions.checkArgument(model != null);
        try {
            //验证token
            DecodedJWT jwt = JWTUtil.verify(model.getToken());
            String userId = jwt.getClaim(WebConstant.DEV_TOKEN_PAYLOAD_KEY).asString();

            if (!Long.valueOf(userId).equals(user.getId())) {
                throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
            } else {
                OpenApp openApp = openAppManager.getByUserId(user.getId());
                OpenAppDevelopSettingsVo vo = new OpenAppDevelopSettingsVo();
                vo.setAppId(openApp.getId().toString());
                vo.setPublicKey(openApp.getPublicKey());
                vo.setAppPublicKey(openApp.getAppPublicKey());
                vo.setEncryptKey(openApp.getEncryptKey());
                vo.setWhiteIps(openApp.getWhiteIps());

                return new ResultData<>(vo);
            }

        } catch (Exception e) {
            log.info("DevelopSettingsToken error", e);
            throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
        }


    }

    @ApiOperation(value = "修改IP白名单")
    @PostMapping("/update—white-ips")
    @ResponseBody
    public ResultData<Boolean> updateWhiteIps(@ApiIgnore @RequestUser User user, @RequestBody ModifyOpenAppWhiteIpsModel model) {
        Preconditions.checkArgument(model != null);
        try {
            //验证token
            DecodedJWT jwt = JWTUtil.verify(model.getToken());
            String userId = jwt.getClaim(WebConstant.DEV_TOKEN_PAYLOAD_KEY).asString();

            if (!Long.valueOf(userId).equals(user.getId())) {
                throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
            }
        } catch (Exception e) {
            log.info("DevelopSettingsToken error", e);
            throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
        }
        String whiteIps = model.getWhiteIps();
        List<String> ips = new ArrayList<>();
        if (!Strings.isNullOrEmpty(whiteIps)) {
            whiteIps = whiteIps.trim();
            //中文逗号换成英文逗号
            whiteIps = whiteIps.replace("，", ",");
            ips = Splitter.on(",").omitEmptyStrings().trimResults().splitToList(whiteIps);
        }
        if (ips.size() == 0) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "请输入ip白名单");
        }
        if (ips.size() > 10) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "ip白名单最多输入10个");
        }

        OpenApp openApp = openAppManager.getByUserId(user.getId());
        openApp.setWhiteIps(ips);
        openAppManager.update(openApp);
        return new ResultData<>(true);
    }


    @ApiOperation(value = "修改应用公钥")
    @PostMapping("/update-app-public-key")
    @ResponseBody
    public ResultData<Boolean> updateAppPublicKey(@ApiIgnore @RequestUser User user, @RequestBody ModifyOpenAppAppPublicKeyModel model) {
        Preconditions.checkArgument(model != null);
        try {
            //验证token
            DecodedJWT jwt = JWTUtil.verify(model.getToken());
            String userId = jwt.getClaim(WebConstant.DEV_TOKEN_PAYLOAD_KEY).asString();

            if (!Long.valueOf(userId).equals(user.getId())) {
                throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
            }
        } catch (Exception e) {
            log.info("DevelopSettingsToken error", e);
            throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
        }
        if (Strings.isNullOrEmpty(model.getAppPublicKey()) || Strings.isNullOrEmpty(model.getAppPublicKey().trim())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "请输入应用公钥");
        }

        OpenApp openApp = openAppManager.getByUserId(user.getId());
        openApp.setAppPublicKey(model.getAppPublicKey().trim());
        openAppManager.update(openApp);
        return new ResultData<>(true);
    }
}
